//
//  SEStarRatingView.swift
//  SmartEyeForPatient
//
//  Created by QDSG on 2021/4/13.
//

import UIKit

private let maxStarsCount: Int = 5
private let minStarsCount: Float = 0

protocol SEStarRatingViewDelegate: NSObjectProtocol {
    // 返回星星评分的分值
    func starRatingView(_ starRatingView: SEStarRatingView, count: Float)
}

class SEStarRatingView: UIView {
    
    weak var delegate: SEStarRatingViewDelegate?

    /// 是否整星, 默认 false
    var wholeStar: Bool = false {
        didSet { showStarRating() }
    }
    
    /// 是否可以滑动, 默认 false
    var slideEnable: Bool = false {
        didSet {
            if slideEnable {
                let pan = UIPanGestureRecognizer(target: self, action: #selector(slideStar(_:)))
                addGestureRecognizer(pan)
            }
        }
    }
    
    /// 是否可以点击, 默认 false
    var clickEnable: Bool = false {
        didSet {
            if clickEnable {
                let tap = UITapGestureRecognizer(target: self,action: #selector(clickStar(_:)))
                addGestureRecognizer(tap)
            }
        }
    }
    
    /// 滑动动画时长, 默认 0.1
    private var starDuration: TimeInterval = 0.1
    
    private var starForegroundView: UIView?
    private var starBackgroundView: UIView?
    
    private var margin: CGFloat = 10
    
    private var _currentStarCount: Float = 0
    /// 当前的星星数量
    var currentStarCount: Float {
        get { _currentStarCount }
        set {
            _currentStarCount = newValue
            showStarRating()
        }
    }
    
    /// 星星总数量
    private var numberOfStars: Int = maxStarsCount
    
    // MARK: - 初始化
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupUI()
    }
}

// MARK: - Setting

extension SEStarRatingView {
    private func setupUI() {
        clipsToBounds = true
        numberOfStars = maxStarsCount
        currentStarCount = minStarsCount
        
        starBackgroundView = initStarView()
        addSubview(starBackgroundView!)
        
        starForegroundView = initStarView()
        addSubview(starForegroundView!)
    }
    
    func drawStar(margin: CGFloat, isFill: Bool) {
        self.margin = margin
        // 添加星星
        let width = (frame.width - margin * CGFloat(numberOfStars - 1)) / CGFloat(numberOfStars)
        for i in 0..<numberOfStars {
            let starFrame = CGRect(x: CGFloat(i) * (width + margin), y: 0, width: width, height: bounds.height)
            let imageView = UIImageView(frame: starFrame)
            imageView.image = isFill ? Asset.iconStarForeground.image : Asset.iconStarBackground.image
            isFill ? starForegroundView?.addSubview(imageView) : starBackgroundView?.addSubview(imageView)
        }
        
        showStarRating()
    }
}

// MARK: - Action Event

extension SEStarRatingView {
    @objc private func slideStar(_ pan: UIPanGestureRecognizer) {
        var offsetX: CGFloat = 0
        switch pan.state {
        case .began:
            offsetX = pan.location(in: self).x
        case .changed:
            offsetX += pan.location(in: self).x
        case .ended:
            offsetX = pan.location(in: self).x
        default:
            break
        }
        currentStarCount = Float((offsetX / bounds.width) * CGFloat(numberOfStars))
        showStarRating()
        protocolHandler()
    }
    
    @objc private func clickStar(_ tap: UITapGestureRecognizer) {
        let offsetX = tap.location(in: self).x
        currentStarCount = Float((offsetX / bounds.width) * CGFloat(numberOfStars))
        showStarRating()
        protocolHandler()
    }
}

// MARK: - Helpers

extension SEStarRatingView {
    private func initStarView() -> UIView {
        let starView = UIView(frame: bounds)
        starView.clipsToBounds = true
        return starView
    }
    
    // 显示评分
    private func showStarRating() {
        UIView.animate(withDuration: starDuration, animations: {
            if !self.wholeStar {
                let starFrame = CGRect(x: 0,
                                       y: 0,
                                       width: (self.bounds.width - self.margin * CGFloat(self.numberOfStars - 1)) / CGFloat(self.numberOfStars) * CGFloat(self.currentStarCount) + CGFloat(ceil(self.currentStarCount) - 1) * self.margin,
                                       height: self.bounds.height)
                self.starForegroundView?.frame = starFrame
            } else { // 只支持整星评分
                let starFrame = CGRect(x: 0,
                                       y: 0,
                                       width: (self.bounds.width - self.margin * CGFloat(self.numberOfStars - 1)) / CGFloat(self.numberOfStars) * CGFloat(ceil(self.currentStarCount)) + CGFloat(ceil(self.currentStarCount) - 1) * self.margin,
                                       height: self.bounds.height)
                self.starForegroundView?.frame = starFrame
            }
        })
    }
    
    /// 协议回调
    private func protocolHandler() {
        if let delegate = delegate {
            var newStar: Float = wholeStar ? Float(ceil(currentStarCount)) : currentStarCount
            if newStar > Float(numberOfStars) {
                newStar = Float(numberOfStars)
            } else if newStar < 0 {
                newStar = 0
            }
            
            delegate.starRatingView(self, count: newStar)
        }
    }
}
